import moment from "dayjs";
import qs from "qs";
export const setTime = (_time, detail = false) => {
  var e = new Date().getTime()
  var d = new Date(moment(_time).valueOf());
  var s = d.getTime()
  var usedTime = e - s //两个时间戳相差的毫秒数
  var days = Math.floor(usedTime / (24 * 3600 * 1000)) //计算出小时数
  var leave1 = usedTime % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
  var hours = Math.floor(leave1 / (3600 * 1000)) //计算相差分钟数
  var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数
  var minutes = Math.floor(leave2 / (60 * 1000))
  let t = ''
  if (days == 0 && hours == 0 && minutes !== 0) {
    t = minutes + '分钟前'
  } else if (days == 0 && hours == 0 && minutes == 0) {
    t = '刚刚'
  } else if (days == 0 && hours !== 0) {
    t = hours + '小时前'
  } else if (days == 1) {
    t = '昨天' + (detail ? d.getHours() + ":" + d.getMinutes() : "")
  } else if (days >= 2) {
    t = moment(s).format("YYYY-MM-DD")
  }
  return t
}
export const noticeTime = (_time, detail = false) => {
  var e = new Date().getTime()
  var d = new Date(moment(_time).valueOf());
  var s = d.getTime()
  var usedTime = e - s //两个时间戳相差的毫秒数
  var days = Math.floor(usedTime / (24 * 3600 * 1000)) //计算出小时数
  var leave1 = usedTime % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
  var hours = Math.floor(leave1 / (3600 * 1000)) //计算相差分钟数
  var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数
  var minutes = Math.floor(leave2 / (60 * 1000))
  let t = ''
  t = moment(s).format("YYYY-MM-DD hh:mm")
  return t
}

export const checkPhone = phone => {
  var myreg = /^1[3|4|5|6|7|8|9][0-9]{9}$/
  return myreg.test(phone)
}


export function debounce(fn, time = 80) {
  let timer = null;
  return function () {
    clearTimeout(timer);
    let args = arguments;
    let self = this;
    timer = setTimeout(function () {
      fn.apply(self, args);
    }, time);
  }
}

export function throttle(fn, time = 80) {
  let now = Date.now();
  return function () {
    let current_now = Date.now();
    let isSend = current_now - now > time;
    if (isSend) {
      now = current_now;
      fn.apply(this, arguments);
    }
  }
}


export function getMonthFirstDay(date = new Date()) {
  date.setDate(1)
  let month = parseInt(date.getMonth() + 1)
  let day = date.getDate()
  if (month < 10) {
    month = '0' + month
  }
  if (day < 10) {
    day = '0' + day
  }
  return date.getFullYear() + '-' + month + '-' + day
}

export function getMonthLastDay(date = new Date()) {
  let year = date.getFullYear();
  let month = date.getUTCMonth() + 1;
  if (month < 10) {
    month = '0' + month;
  }
  let day = new Date(year, month, 0);
  return `${year}-${month}-${day.getDate()}`
}

export const Verify = {
  idCard(str = "") {
    var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
    return reg.test(str);
  },
  strLen(str = "", min = 6, max = null) {
    var reg = new RegExp(`^\\S{${min},}$`);
    if (max) {
      reg = new RegExp(`^\\S{${min},${max}}$`);
    }
    return reg.test(str);
  }
}
export let types = {};

for (var i = 0, type; type = ['String', 'Array', 'Number', 'Object', 'Undefined', 'Null', 'Function', "Symbol", 'RegExp', 'Date', 'Boolean'][i++];) {
  (function (item) {
    types['is' + item] = function (variable) {
      return Object.prototype.toString.call(variable) === '[object ' + item + ']';
    }
  })(type)
}


export const strategies = {
  isType(val, errMsg, type) {
    if (!types['is' + type] || !types['is' + type](val)) {
      return errMsg;
    }
  },
  isIdCard(val, errMsg, ) {
    var reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
    if (!reg.test(val)) {
      return errMsg;
    }
  },
  isNotEmpty(val, errMsg) {
    if (!val) {
      return errMsg;
    }
  },
  minLength(val, errMsg, len) {
    if (val.length < len) {
      return errMsg;
    }
  },
  maxLength(val, errMsg, len) {
    if (val.length > len) {
      return errMsg;
    }
  },
  isMoboleNumber(val, errMsg) {
    if (!/^1[2-9][0-9]{9}$/.test(val)) {
      return errMsg;
    }
  },
  isContactNumber(phone, errmsg) {
    var myreg = /^1[3|4|5|6|7|8|9][0-9]{9}$/;
    var phonereg = /^[0-9]{3,}[-][0-9]{4,}$/;
    if (
      !myreg.test(phone) &&
      !phonereg.test(phone)
    ) {
      return errmsg;
    }
  },
  isEmail(str, errMsg) {
    var reg = /^\w+@[a-zA-Z0-9]{2,10}(?:\.[a-z]{2,4}){1,3}$/;
    if (!reg.test(str)) {
      return errMsg;
    }
  },
  isChina(str, errMsg) {
    var reg = /^[\u4E00-\u9FA5]{2,4}$/; /*定义验证表达式*/
    if (!reg.test(str)) {
      return errMsg;
    }
  },
  require(str, errMsg) {
    if (Array.isArray(str) && !str.length) return errMsg;
    if (!str) {
      return errMsg;
    }
  }
};

export function Validator() {
  return new Validator.prototype._init();
}

Validator.prototype.add = function (val, rules) {
  var self = this;
  if (types.isArray(rules)) {
    for (var i = 0, rule; rule = rules[i++];) {
      if (rule.strategy) {
        continue
      }
      (function (rule) {
        self.cache.push(function () {
          return strategies[rule.strategy](val, rule.errMsg, rule.reg)
        })
      })(rule)
    }
  } else if (types.isObject(rules) && rules.strategy) {
    self.cache.push(function () {
      return strategies[rules.strategy](rules.val, rules.errMsg, rules.reg)
    })
  } else {
    return false;
  }
}

Validator.prototype.start = function () {
  for (var i = 0, validatorFunc; validatorFunc = this.cache[i++];) {
    var msg = validatorFunc();
    if (msg) {
      return msg;
    }
  }

  return false;
}

Validator.prototype._init = function () {
  this.cache = [];
  return this;
}

Validator.prototype._init.prototype = Validator.prototype;

export const validataFunc = function (arr) {
  var validator = Validator();
  if (types.isArray(arr)) {
    arr.forEach(item => {
      validator.add(item.val || '', item.rules || item);
    });
  } else {
    validator.add(arr.val || '', arr.rules || arr);
  }

  return validator.start();
}
/**
 * 
 * @param {*} day 多少天前
 * @param {*} date 哪一天
 */
export function getBeforeDaySeconds(day = 1, date = Date.now(), ) {
  let milliseconds = 86400000 * day;
  return date - milliseconds
}


/**
 * 获取年月
 * @param {*} y 
 * @param {*} month 
 * @param {*} all 
 */
export function getYearAndMonth(y = 2017, month = 12, all = true) {
  let date = new Date();
  let months = [];
  let years = [];
  let datalist = [];
  if (all) {
    months.push("全年");
  }
  for (var j = 1; j < 13; j++) {
    let m = j + "月";
    months.push(m);
  }

  for (var i = date.getFullYear(); i >= 2017; i--) {
    years.push(i);
    let obj = {};
    let m = [];
    obj.text = i;
    months.forEach((j, index) => {
      let monthObj = {};
      monthObj.text = j;
      monthObj.id = Number(`${i}${index}`);
      m.push(monthObj);
    });
    obj.children = m;
    datalist.push(obj);
  }
  return datalist;
}
/**
 * 获取input值
 * @param {*} dataList 需要获取值的 dataList 数组
 * @param {*} key 根据key获取值
 * @param {*} cb 效验回调
 */
export const getFormData = (dataList = [], key = "_key", cb = () => {}) => {
  let obj = {};
  let valid = [];
  dataList.forEach(i => {
    let val = i.value;
    if (i.other) {
      let tmp = getFormData([i.other], key, cb);
      Object.assign(obj, tmp);
    }
    if (i.hide) {
      val = "";
    } else {
      if (i.type == "picker") {
        if (i.mode == "multiSelector") {
          if (val.length) {

            val = i.range.map((i, index) => {
              return i[val[index] || 0];
            });
          }
        } else if (i.mode == 'date' || i.mode == 'time') {

        } else {
          let t = i.range[val];
          if (typeof t === "object") {
            val = t.id || t.value;
          } else {
            val = t
          }
        }
      } else if (i.type == "select" || i.type == 'upload') {
        val = i.value;
      } else if (i.type == "checkbox") {
        let checks = (i.range || []).filter(i => i.checked);
        val = checks.map(i => i.value);
      } else if (i.type == 'radio') {
        let arr = (i.range || []).filter(i => i.checked).map(i => i.value);
        val = i.multiple ? arr : arr[0] || ''
      }
    }
    if (i.require) {
      let name = (i.name || i._name || "").replace(":", "");
      name = name.replace("：", "");
      let errMsg = validataFunc([{
        errMsg: name + '为必填项!',
        val: val,
        strategy: "require"
      }]);
      if (errMsg) {
        valid.push({
          errMsg,
          ...i
        });
      }
    }
    obj[i[key]] = val || '';
  })
  if (valid.length && typeof cb === 'function') {
    console.log(valid, "?valid")
    cb(valid)
  }
  return obj;
}
/**
 * @param {*} dataList 初始化值
 */
export function resetFormData(dataList = []) {
  dataList.forEach(i => {
    if (types.isArray(i.value)) {
      i.value.length = 0;
      i.value = [];
    } else {
      i.value = "";
    }
  })
}

/**
 * 获取并设置 input值
 * @param {*} e 事件event
 * @param {*} item Object
 * @param {*} custom 自定义值
 */
export function getInputValue(e, item, custom) {
  if (item.type == 'upload' || !types.isObject(e)) {
    return e;
  }
  let v = e.detail.value;
  let {
    type,
    mode,
    value,
    range
  } = item;
  if (type == "picker") {
    if (mode == "multiSelector") {
      item.value = range.map((i, index) => v[index] || 0);
      return range.map((i, index) => {
        return i[v[index] || 0];
      });
    } else if (mode == "date" || mode == "time") {
      item.value = v;
      return v;
    } else {
      let tmp = item.range[v];
      item.value = v;
      return tmp;
    }
  } else if (item.type == "select") {
    return custom;
  } else if (item.type == "radio") {
    return e;
  } else if (item.type == "checkbox") {
    return e;
  } else {
    return v;
  }
}



/**
 * 深拷贝
 * @param {*} obj 拷贝对象(object or array)
 * @param {*} cache 缓存数组
 */
export function deepCopy(obj, cache = []) {
  // typeof [] => 'object'
  // typeof {} => 'object'
  if (obj === null || typeof obj !== 'object' || obj instanceof Date) {
    if (obj instanceof Date) {
      return new Date(obj.valueOf)
    }
    return obj
  }
  // 如果传入的对象与缓存的相等, 则递归结束, 这样防止循环
  /**
   * 类似下面这种
   * var a = {b:1}
   * a.c = a
   * 资料: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value
   */
  const hit = cache.filter(c => c.original === obj)[0]
  if (hit) {
    return hit.copy
  }

  const copy = Array.isArray(obj) ? [] : {}
  // 将copy首先放入cache, 因为我们需要在递归deepCopy的时候引用它
  cache.push({
    original: obj,
    copy
  })
  Object.keys(obj).forEach(key => {
    copy[key] = deepCopy(obj[key], cache)
  })

  return copy
}

export function stringToJSON(objStr = "", def = {}, type = "object") {
  let ret = def;
  try {
    ret = JSON.parse(objStr)
  } catch (err) {

  }
  if (typeof ret !== type) {
    ret = def;
  }
  return ret;
}
/**
 * 打开文件
 * @param {*} file 需要打开的文件链接
 */
// #ifdef H5
// let a = document.createElement('a');
// a.download = true;
// a.href = file.url;
// a.click();
// a = null;
// #endif
export function openFile(file) {
  if (file.isImage) {
    uni.previewImage({
      current: file.url,
      urls: [file.url]
    })

  } else {

    uni.openDocument({
      filePath: file.url,
      fail(err) {
        console.log(err,123123)
        uni.showToast({
          title: "打开失败",
          icon: "none"
        })
      }
    });
  }
}
/**
 * 树形数据转换
 * @param {*} data
 * @param {*} id
 * @param {*} pid
 */
export function treeDataTranslate(data, id = 'id', pid = 'pid', childrenKey = 'children') {
  var res = []
  var temp = {}
  for (var i = 0; i < data.length; i++) {
    temp[data[i][id]] = data[i];
  }
  for (var k = 0; k < data.length; k++) {
    if (!temp[data[k][pid]] || data[k][id] === data[k][pid]) {
      res.push(data[k])
      continue
    }
    if (!temp[data[k][pid]][childrenKey]) {
      temp[data[k][pid]][childrenKey] = []
    }
    temp[data[k][pid]][childrenKey].push(data[k])
    data[k]['_level'] = (temp[data[k][pid]]._level || 0) + 1;
  }
  return res
}

/**
 * 树形数据转 array
 * @param {*} nodes 
 */
export function TreeToArray(nodes = [], key = "children", del = !0) {
  var r = [];
  if (Array.isArray(nodes)) {
    for (var i = 0, l = nodes.length; i < l; i++) {
      r.push(nodes[i]); // 取每项数据放入一个新数组
      if (Array.isArray(nodes[i][key]) && nodes[i][key].length > 0) {
        // 若存在children则递归调用，把数据拼接到新数组中，并且删除该children
        r = r.concat(TreeToArray(nodes[i][key], key, del));
      }
      del && delete nodes[i][key]
    }
  }
  return r;
}

// 分时函数
export function timeChunk(arr = [], fn = false, count = 10, interval = 80) {
  if (typeof fn !== 'function' || !Array.isArray(arr)) return;
  let obj, timer, index = 0;
  let start = function () {
    for (let i = 0; i < Math.min(count || 1, arr.length); i++) {
      obj = arr.shift();
      fn(obj, index);
      index++;
    }
  }

  return function () {
    timer = setInterval(function () {
      if (arr.length === 0) {
        return clearInterval(timer);
      }
      start();
    }, interval)
  }
}


/**
 * 获取字典数据列表
 * @param dictType  字典类型
 */
export function getDictDataList(dictType, dictList = []) {
  const type = dictList.find((element) => (element.field === dictType))
  if (type) {
    return (type.children || [])
  } else {
    return []
  }
}

/**
 * 获取字典名称
 * @param dictType  字典类型
 * @param dictValue  字典值
 */
export function getDictLabel(dictType, dictValue, dictList = []) {
  const type = dictList.find((element) => (element.field === dictType))
  console.log(type,'???dictList')
  if (type) {
    const val = (type.children || []).find((element) => (element.value == dictValue + ''))
    if (val) {
      return val.label
    } else {
      return dictValue
    }
  } else {
    return dictValue
  }
}

export function UUID() {
  const s = [];
  const hexDigits = '0123456789abcdef';
  for (let i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  s[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = '-';
  s.push(+new Date());
  const uuid = s.join('');
  return uuid;
}


export function getPageScene(p) {
  let s = p.scene || "";
  if (s) {
    s = decodeURIComponent(s);
    let obj = qs.parse(s);
    return obj;
  }
  return {}
}

export default {
  checkPhone,
  setTime,
  debounce,
  Validator,
  validataFunc,
  getFormData,
  getYearAndMonth,
  getInputValue,
  timeChunk,
}